﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace MOSSLoadTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string ServiceToUrl(string Url, string Service)
        {
            string webUrl = Url.Trim();
            if (webUrl.Substring(webUrl.Length - 1) != "/")
            {
                return webUrl + "/_vti_bin/" + Service + ".asmx";
            }
            return webUrl + "_vti_bin/" + Service + ".asmx";

        }

        private SiteDataWS.SiteData dataObj = new MOSSLoadTest.SiteDataWS.SiteData();

        private bool connected;

        private bool TestUrl(string Url)
        {
            // Save to rollback in case of error
            string localUrl = dataObj.Url;
            dataObj.Url = ServiceToUrl(Url, "SiteData");
            try
            {
                this.Cursor = Cursors.WaitCursor;
                dataObj.PreAuthenticate = true;
                string tempUrl = dataObj.Url; // Discover resets the URL
                dataObj.Discover();
                dataObj.Url = tempUrl;
                connected = true;
                this.Cursor = Cursors.Default;

            }
            catch (Exception ex)
            {
                dataObj.Url = localUrl;
                MessageBox.Show(ex.Message, "Error");
                return false;
            }
            return true;


        }

        private string credUser = "";
        private string credPass = "";
        private string credDomain = "";
        private bool credDefault;

        private bool Login()
        {
            LoginForm lf = new LoginForm();
            lf.CredentialDomain = credDomain;
            lf.CredentialUserName = credUser;
            lf.CredentialPassword = credPass;

            if (textBox1.Text != String.Empty)
            {
                lf.UrlServer = textBox1.Text;
            }
            lf.ShowDialog(this);
            if (Certificate.IsSelected)
            {
                dataObj.ClientCertificates.Clear();
                dataObj.ClientCertificates.AddRange(Certificate.Certificates);


            }

            if (lf.Canceled) return false;

            connected = false;
            if (lf.UseCurrentUser)
            {
                dataObj.Credentials = System.Net.CredentialCache.DefaultCredentials;
                credDefault = true;
                dataObj.Credentials = System.Net.CredentialCache.DefaultCredentials;
            }
            else
            {
                System.Net.NetworkCredential credential = new System.Net.NetworkCredential(lf.CredentialUserName,
                    lf.CredentialPassword, lf.CredentialDomain);
                dataObj.Credentials = credential;
                credPass = lf.CredentialPassword;
                credDomain = lf.CredentialDomain;
                credUser = lf.CredentialUserName;
                credDefault = false;

            }
            if (lf.UrlServer != String.Empty)
            {
                textBox1.Text = lf.UrlServer;
            }
            if (!TestUrl(lf.UrlServer)) return false;
            this.Cursor = Cursors.Default;
            return true;

        }



        private DateTime expireTime = DateTime.Now;
        private string url = null;
        private void button1_Click(object sender, EventArgs e)
        {
            if (!Login()) return;

            listView1.Items.Clear();
            textBox2.Text = "0";
            textBox3.Text = "0";
            textBox4.Text = maskedTextBox2.Text;
            Crawler.Count = 0;
            Crawler.ErrorCount = 0;
            Crawler.Abort = false;
            button1.Enabled = false;
            timer1.Interval = 1000;

            int minutes = Int32.Parse(maskedTextBox2.Text.Split(':')[0])*60;
            minutes += Int32.Parse(maskedTextBox2.Text.Split(':')[1]);


            expireTime = DateTime.Now.AddMinutes((double)minutes);
            timer1.Enabled = true;

            url = textBox1.Text;
            button3.Enabled = true;
            for (int i = 0; i < Int32.Parse(maskedTextBox1.Text); i++ )
            {
                Thread tr = new Thread(new ThreadStart(NewThread));
                tr.Start();
            }

        }

        private void NewThread()
        {
            while (!Crawler.Abort)
            {
                Crawler crl = new Crawler(dataObj);
                crl.ProcessWeb(url);
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            
            textBox2.Text = Crawler.Count.ToString();
            textBox3.Text = Crawler.ErrorCount.ToString();
            textBox4.Text = ((TimeSpan)(expireTime - DateTime.Now)).Hours.ToString("000") + "h:" + ((TimeSpan)(expireTime - DateTime.Now)).Minutes.ToString("00")+"m";
            PageError err;
            while ((err = Crawler.GetError()) != null)
            {
                ListViewItem items = new ListViewItem(new string[]{err.ErrorCode, err.Url, err.HtmlCode});
                listView1.Items.Add(items);
            }
            if ((DateTime.Now > expireTime || Crawler.Abort) && !button1.Enabled)
            {
                Crawler.Abort = true;
                if (!button1.Enabled)
                {
                    button1.Enabled = true;
                    MessageBox.Show(String.Format("Load Test Finished by Time Constraint.\n{0} Hit(s) {1} Error(s)", Crawler.Count, Crawler.ErrorCount));
                }
                timer1.Enabled = false;
                textBox4.Text = "000h:00m";

            }
            else
            {
                textBox4.Text = ((TimeSpan)(expireTime - DateTime.Now)).Hours.ToString("000") + "h:" + ((TimeSpan)(expireTime - DateTime.Now)).Minutes.ToString("00") + "m" + ((TimeSpan)(expireTime - DateTime.Now)).Seconds.ToString("00")+"s";

            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to quit?", "Warning", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                Crawler.Abort = true;
                return;
            }
            e.Cancel = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            AboutBox1 abt = new AboutBox1();
            abt.ShowDialog();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Crawler.Abort = true;
            button1.Enabled = true;
            timer1.Enabled = false;

            MessageBox.Show(String.Format("Load Test Interrupted by User.\n{0} Hit(s) {1} Error(s)", Crawler.Count, Crawler.ErrorCount));

        }

        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            if (((ListView)sender).SelectedItems.Count > 0)
            {
                ErrorDetails ed = new ErrorDetails();
                ListViewItem li = ((ListView)sender).SelectedItems[0];
                ed.textError.Text = li.SubItems[0].Text;
                ed.textUrl.Text = li.SubItems[1].Text;
                ed.textHtml.Text = li.SubItems[2].Text;
                ed.ShowDialog();
                
            }
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }
    }
}
